package gat.api.config;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bitsun.core.common.constant.HeaderConstants;
import com.bitsun.core.common.constant.RuntimeContext;
import com.bitsun.core.common.constant.RuntimeContextHolder;
import com.bitsun.core.common.enums.UserTypeEnum;
import com.bitsun.core.common.exception.AppException;
import com.bitsun.core.common.web.CurrentUser;
import gat.RedisService;
import gat.common.constant.RedisNoConstants;
import gat.common.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {

    @Resource
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {

        

        boolean modelFlag = request.getRequestURI().startsWith("/model/");

        String token = request.getHeader(HeaderConstants.token);
        RuntimeContext context = ObjectUtil.isNull(RuntimeContextHolder.currentRuntimeContext()) ? new RuntimeContext() : RuntimeContextHolder.currentRuntimeContext();
        context.setRequest(request);
        context.setResponse(response);
        String channel = request.getParameter("channel");
        context.putCache("channel", channel);
        String phoneBrand1 = request.getHeader("phoneBrand");
        String oaId = request.getHeader("oaId");
        if (ObjectUtil.isNotNull(phoneBrand1) && ObjectUtil.isNotNull(oaId)) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("phoneBrand", phoneBrand1);
            jsonObject.put("oaId", oaId);
            context.putCache("phoneInfo",jsonObject.toJSONString());
        }
        RuntimeContextHolder.setCurrentRuntimeContext(context);
        // 获取token并且解析
        if (StringUtils.isNotBlank(token)) {
            //getUserDetailByToken(context,token);

            String user = JwtUtil.verifyToken(token);
            if (Objects.isNull(user)) {
                // throw new AppException("未登录", "000001");
                if (modelFlag) {
                    response.sendRedirect("/model/user/phoneLogin");
                    return false;
                } else {
                    throw new AppException("未登录", "000001");
                }
            }
            CurrentUser currentUser = JSON.parseObject(user, CurrentUser.class);

            String redisToken = redisService.get(RedisNoConstants.token + currentUser.getId());
            if (StringUtils.isBlank(redisToken)) {
                // throw new AppException("登录信息已过期", "000001");
                if (modelFlag) {
                    response.sendRedirect("/model/user/phoneLogin");
                    return false;
                } else {
                    throw new AppException("登录信息已过期", "000001");
                }
            }
            String newToken = JwtUtil.refreshToken(token);
            if (StringUtils.isNotBlank(newToken)){
                long expireTime = 1296000L;
                response.setHeader("Access-Control-Expose-Headers","token");
                response.setHeader(HeaderConstants.token,newToken);
                if (StringUtils.equals(currentUser.getUserType(),UserTypeEnum.ADMIN.getCode())){
                    expireTime = 4 * 3600L;
                }
                redisService.set(RedisNoConstants.token+currentUser.getId(),newToken,expireTime);
            }
            log.info("当前用户信息：{}", JSON.toJSONString(currentUser));
            context.setCurrentUser(currentUser);
            context.putCache("user", currentUser);

            if (StringUtils.isNotBlank(phoneBrand1)) {
                context.putCache("phoneBrand", phoneBrand1);
            }

            return true;
        } else {
            if (modelFlag) {
                response.sendRedirect("/model/user/phoneLogin");
                return false;
            } else {
                if (StringUtils.equals(request.getRequestURI(), "/error")) {
                    response.sendRedirect("/model/index");
                   return true;
                }
                throw new AppException("未登录", "000001");
            }


        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView view) {


    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception e) {
        // 手动删除,防止内存泄漏
        RuntimeContextHolder.clear();
        MDC.clear();
    }

}
